#include "Scene.h"
#include<QDir>
#include <iostream>
#include <QElapsedTimer>

using namespace std;

Scene::Scene(void)
{
}

Scene::~Scene(void)
{
}
void Scene::onMessageLogged( QOpenGLDebugMessage msg){
	qDebug()<<msg;
}

bool Scene::init(){
    prepare_program();
    _objs.push_back(new Shape());
    _objs.push_back(new Shape());
    _objs.push_back(new Shape());
    QElapsedTimer _time;
    qint64 nsec;

    _objs[0]->init(_shader_program);
    _time.start();
    _objs[0]->load_obj(":/QTGL/models/tyra.obj");
    _objs[0]->rotate(QVector3D(0,1,0),180.0);
    _objs[0]->translate(QVector3D(-2.0,0,0));
    nsec = _time.nsecsElapsed();

    qDebug()<<"Elapsed tyra : "<<(double)nsec/1000000000.0;

    _objs[1]->init(_shader_program);
    _time.restart();
    _objs[1]->load_obj(":/QTGL/models/armadillo.obj");
    _objs[1]->rotate(QVector3D(0,1,0),180.0);

    nsec = _time.nsecsElapsed();
    qDebug()<<"Elapsed tyra : "<<(double)nsec/1000000000.0;

    _objs[2]->init(_shader_program);
    _time.restart();
    _objs[2]->load_obj(":/QTGL/models/bunny.obj");
    _objs[2]->rotate(QVector3D(0,1,0),90.0);
    _objs[2]->translate(QVector3D(2.0,-0.5,0));
    nsec = _time.nsecsElapsed();
    qDebug()<<"Elapsed tyra : "<<(double)nsec/1000000000.0;

    _cam.AbsoluteZoom(5);



    return true;

}

bool Scene::prepare_program(){
    _shader_program = new QOpenGLShaderProgram();

    if (!_shader_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/QTGL/shaders/phong.vert"))
    {
        qCritical() << "error";
        return false;
    }
    if (!_shader_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/QTGL/shaders/phong.frag"))
    {
        qCritical() << "error";
        return false;
    }
    if (!_shader_program->link())
    {
        qCritical() << "error";
        return false;
    }

    return true;
}

void Scene::resize(int _w, int _h){
	this->_w = _w;
	this->_h = _h;
	glViewport(0,0, _w, _h);
		
}

void Scene::render(){
    QMatrix4x4 _pm, _mm;
    if(_h==0) _h = 1;
    float _aspect = _w/_h;

    glEnable(GL_DEPTH_TEST);
    glFrontFace(GL_CCW);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    _shader_program->setUniformValue("specular_power",128);
    _shader_program->setUniformValue("specular_albedo",QVector3D(0.5,0.5,0.5));

    _pm.perspective(90,_aspect,0.1,100);
    _mm.lookAt(_cam.getEye(),_cam.getCenter(),_cam.getUp());

    for(auto s:_objs){
        s->setModelMatrix(_mm);
        s->setProjectionMatrix(_pm);
        s->draw();
    }
  }

void Scene::strafe_lr(float _amount){
	_cam.StrafeLeft(_amount);
}

void Scene::strafe_ud(float _amount){
	_cam.StrafeUp(_amount);
}

void Scene::rotate_lr(float _amount){
	_cam.RotateLeft(_amount);
}

void Scene::rotate_ud(float _amount){
	_cam.RotateUp(_amount);
}

void Scene::zoom(float _amount){
    _cam.ZoomIn(_amount);
}
